home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / tjgold.zip / INSTALL.002 / GOLDIO3.PAS < prev    next >
Pascal/Delphi Source File  |  1995-07-12  |  58KB  |  2,082 lines

  1. {--------------------------------------------------------------------------}
  2. {                Product: TechnoJock's Turbo Toolkit                       }
  3. {                Version: GOLD                                             }
  4. {                Build:   1.01                                             }
  5. {                                                                          }
  6. {                Copyright 1986-1995  TechnoJock Software, Inc.            }
  7. {                           All Rights Reserved                            }
  8. {                          Restricted by License                           }
  9. {--------------------------------------------------------------------------}
  10.  
  11.                     {*********************************}
  12.                     {**       Unit:   GOLDIO3       **}
  13.                     {*********************************}
  14.  
  15. {+++++++++++++++++++++++++++++++} unit GOLDIO3; {++++++++++++++++++++++++++++}
  16.  
  17. {$I GOLDFLAG.INC}
  18. {$IFNDEF GOLDIO3}
  19.    {$DEFINE GOLDIO3}
  20. {$ENDIF}
  21.  
  22. {++++++++++++++++++++++++++++++++} INTERFACE {+++++++++++++++++++++++++++++++}
  23.  
  24. uses DOS, CRT,
  25.      GoldAttr, GoldHard, GoldTint, GoldMisc, GoldKey, GoldFast,
  26.      GoldWin, GoldLink, GoldStr, GoldDate, GoldIO,
  27.      GoldList, GoldIO2, GoldReal, GoldCal, GoldMemo;
  28.  
  29. const
  30.    FixedFld = succ(ListFld);
  31.    RealStrElementLength = 30;
  32.  
  33. type
  34.    FixedRealStr = string[RealStrElementLength];
  35.  
  36.    FixedInfoPtr = ^FixedInfo;
  37.    FixedInfo = record
  38.       WholeP: byte;
  39.       WholeStr: FixedRealStr;
  40.       DPStr: FixedRealStr;
  41.       Pad:char;
  42.       EMax:extended;
  43.       EMin:extended;
  44.       EDelta:extended; {used in spin field}
  45.    end; {FixedInfo}
  46.  
  47.    IO3Set = record
  48.       SpinUpKey: word;
  49.       SpinDownKey: word;
  50.       SpinUp: char;
  51.       SpinDown: char;
  52.       DropDownKey: word;
  53.       DropDown: char;
  54.       IconPadLeft:char;
  55.       IconPadRight:char;
  56.    end; {IO3Set}
  57.  
  58. procedure AddHotKeyField(FieldID:integer; Key:word; Action:gAction);
  59. procedure FixedRealField(FieldID:integer; var Realvar:Extended;Whole,DP:byte;Min,Max:extended);
  60. procedure SpinLongField(FieldID:integer; var LongIntvar:LongInt;Width:byte;Min,Max,Increment : LongInt);
  61. procedure SpinRealField(FieldID:integer; var Realvar:extended;Whole,DP:byte;Min,Max,Delta:extended);
  62. procedure SpinDateField(FieldID:integer; var Datevar:Dates; DateFormat:gDate;DefFormat:string; Min,Max : Dates);
  63. procedure DropDateField(FieldID:integer; var Datevar:Dates; DateFormat:gDate;DefFormat:string; Min,Max : Dates);
  64. procedure SpinDropDateField(FieldID:integer; var Datevar:Dates; DateFormat:gDate;
  65.                             DefFormat:string; Min,Max : Dates);
  66. procedure DropListField(FieldID:integer; width:byte; var SelectedItem:integer);
  67. procedure SpinListField(FieldID:integer; width:byte; var SelectedItem:integer);
  68. procedure SpinDropListField(FieldID:integer; width:byte; var SelectedItem:integer);
  69. procedure EditDropListField(FieldID:integer; var Strvar:string;FieldL,MaxL:byte);
  70. procedure HotspotField(FieldID:integer; W,D: byte; Action:gAction);
  71. procedure BrowseField(FieldID:integer; width,depth:byte; var ListDetails: ListCfg);
  72. procedure MemoField(FieldID:integer; width,depth:byte;var Memo:MemoCfg);
  73.  
  74. var
  75.    IO3Vars: IO3Set;
  76.  
  77. {+++++++++++++++++++++++++++++} IMPLEMENTATION {+++++++++++++++++++++++++++++}
  78.  
  79.                            {*******************}
  80.                            {**  HotKeyField  **}
  81.                            {*******************}
  82. {$IFOPT F-}
  83.    {$DEFINE FOFF}
  84.    {$F+}
  85. {$ENDIF}
  86. procedure NoDisplay(FSP:FieldSettingsPtr;Status:gStatus);
  87. {Doesn't draw anything}
  88. begin
  89. end; { FixedDisplay }
  90.  
  91. function NoKeyHandler(InKey:word;X,Y:byte):gAction;
  92. begin
  93.    NoKeyHandler := none;
  94. end; { NoKeyHandler }
  95.  
  96. function StandardHotKeyHandler(FNP:FieldSettingsPtr;var Key:word;var Act:gAction):boolean;
  97. {}
  98. var Selected: boolean;
  99. begin
  100.    if FNP <> nil then with FNP^ do
  101.       Selected := (Key <> 0) and (Key = HotKey) and (Active = FldOn)
  102.    else
  103.       Selected := false;
  104.    if Selected then
  105.    begin
  106.       Key := 0;  {absorb the key}
  107.       Act := gAction(FNP^.OMisc);
  108.    end;
  109.    StandardHotkeyHandler := Selected;
  110. end; { StandardHotKeyHandler }
  111. {$IFDEF FOFF}
  112.    {$F-}
  113.    {$UNDEF FOFF}
  114. {$ENDIF}
  115.  
  116. procedure AddHotKeyField(FieldID:integer; Key:word; Action:gAction);
  117. {}
  118. var FieldDetails: FieldSettingsPtr;
  119. begin
  120.    CheckFormAllocation;
  121.    FieldDetails := AllocateNewField;
  122.    if FieldDetails <> nil then
  123.       with FieldDetails^ do
  124.       begin
  125.          ID := FieldID;
  126.          if ID = 1 then
  127.          begin
  128.             Upfield := IDLastField;
  129.             Downfield := 2;
  130.             Leftfield := IDLastField;
  131.             Rightfield := 2;
  132.          end
  133.          else
  134.          begin
  135.             Upfield := pred(ID);
  136.             Downfield := succ(ID);
  137.             Leftfield := pred(ID);
  138.             Rightfield := succ(ID);
  139.          end;
  140.          X1 := 1;
  141.          Y1 := 1;
  142.          Y2 := 1;
  143.          IconWidth := 0;
  144.          HotKey := Key;
  145.          HotKeyHook := StandardHotKeyHandler;
  146.          DisplayHook := NoDisplay;
  147.          ProcessKeyHook := NoKeyHandler;
  148.          SuspendHook := SuspendOK;
  149.          RefreshFieldHook := DoNothing;
  150.          UpdateVarHook := DoNothing;
  151.          DisposeHook := BasicDisposeHook;
  152.          Message := '';
  153.          FieldLabel := '';
  154.          FieldFmt := '';
  155.          MsgX := 0;
  156.          MsgY := 0;
  157.          FieldRules := 0;
  158.          inc(IOVars.Form[IOVars.CurrentForm]^.TotalFields);
  159.          AllowChar := [NoChar];
  160.          DisAllowChar := [NoChar];
  161.          FieldType := IOHotkey;
  162.          UsesCursors := false;
  163.          UsesEnter := false;
  164.          Active := FldOn;
  165.          Visible := false;
  166.          OMisc := ord(Action);
  167.       end;
  168. end; {AddHotKeyField}
  169.  
  170.                          {************************}
  171.                          {**  Fixed Real Field  **}
  172.                          {************************}
  173.  
  174. procedure Condense(FSP:FieldSettingsPtr);
  175. {Compacts the input string}
  176. begin
  177.    with FSP^ do
  178.    with FixedInfoPtr(DataPtr)^ do
  179.    begin
  180.       if WholeStr [1] = '-' then
  181.       begin
  182.          delete(WholeStr,1,1);
  183.          WholeStr := '-'+padright(Strip('A',Pad,WholeStr),pred(WholeP),Pad);
  184.       end
  185.       else
  186.          WholeStr := padright(Strip('A',Pad,WholeStr),WholeP,Pad);
  187.       DPStr := padleft(Strip('A',Pad,DPStr),RealDP,'0');
  188.       end;
  189. end; { Condense }
  190.  
  191. procedure FixedSetNull(FSP:FieldSettingsPtr);
  192. {}
  193. begin
  194.    with FSP^ do
  195.    with FixedInfoPtr(DataPtr)^ do
  196.    begin
  197.       CursorX := 1;
  198.       StrLocX := pred(wholep);
  199.       WholeStr:= replicate(WholeP,Pad);
  200.       DPStr :=  replicate(RealDP,Pad);
  201.    end;
  202. end; {FixedSetNull}
  203.  
  204. procedure FixedRedisplay(FSP:FieldSettingsPtr;Status:gStatus);
  205. {}
  206. var
  207.   ValStr: StrScreen;
  208.   A,P:byte;
  209. begin
  210.    with FSP^ do
  211.    with IOVars.Form[IOVars.CurrentForm]^ do
  212.    with FixedInfoPtr(DataPtr)^ do
  213.    begin
  214.       if not (Status in [Activate,HiStatus]) then
  215.          Condense(FSP);
  216.       ValStr := WholeStr;
  217.       if RealDP > 0 then
  218.          ValStr := ValStr+DecimalSep+DPStr;
  219.       if Status in [Activate,HiStatus] then
  220.       begin
  221.           GotoXY(X1+pred(StrLocX),Y1);
  222.           if FirstCharPress
  223.           and ((length(WholeStr) <> 0) or (length(WholeStr) <> 0))
  224.           and IsRule(FieldRules,EraseDefault) then
  225.           begin
  226.              P := 1;
  227.              while (WholeStr[P] = Pad) and (P <= length(WholeStr)) do
  228.                 inc(P);
  229.              if P <= length(WholeStr) then
  230.              begin
  231.                WriteAT(X1,Y1,Col[IOEditHi],copy(ValStr,1,pred(P)));
  232.                WriteAT(X1+pred(P),Y1,Col[IOEditErase],copy(ValStr,P,80));
  233.              end
  234.              else
  235.                WriteAT(X1,Y1,Col[IOEditErase],ValStr)
  236.           end
  237.           else
  238.              WriteAT(X1,Y1,Col[IOEditHi],ValStr);
  239.           exit;
  240.       end
  241.       else if Active = FldOn then
  242.          A := Col[IOEditNorm]
  243.       else
  244.          A := Col[IOEditOff];
  245.       WriteRight(X2,Y1,A,ValStr);
  246.    end;
  247. end; { FixedRedisplay }
  248.  
  249. function FixedValStr(FSP:FieldSettingsPtr): string;
  250. {INTERNAL - returns the field value in a real string format}
  251. var ValStr: string;
  252. begin
  253.    if (FSP <> nil) then
  254.    begin
  255.       with FSP^ do
  256.       with FixedInfoPtr(DataPtr)^ do
  257.       begin
  258.          Condense(FSP);
  259.          ValStr := WholeStr+DecimalSep+DPStr;
  260.          ValStr := strip('A',Pad,ValStr);
  261.       end;
  262.       FixedValStr := ValStr
  263.   end
  264.   else
  265.      FixedValStr := '';
  266. end; { FixedValStr }
  267.  
  268.  
  269. {$IFOPT F-}
  270.    {$DEFINE FOFF}
  271.    {$F+}
  272. {$ENDIF}
  273. procedure FixedRefresh(FSP:FieldSettingsPtr);
  274. {Updates the field's display based on the new value of the real field}
  275. var
  276.    TempStr: string;
  277.    P: byte;
  278. begin
  279.    if (FSP <> nil) then
  280.       with FSP^ do
  281.       with FixedInfoPtr(DataPtr)^ do
  282.       begin
  283.          DPStr := replicate(RealDP,Pad);
  284.          if IsRule(FieldRules,SuppressZero)
  285.          and (RPtr^ = 0.0) then
  286.              WholeStr := replicate(WholeP,Pad)
  287.          else
  288.          begin
  289.             TempStr := RealToStr(RPtr^,RealDP);
  290.             P := pos('.',TempStr);
  291.             if (P = 0) or (RealDP = 0) then
  292.                WholeStr := padright(TempStr,WholeP,Pad)
  293.             else
  294.             begin
  295.                WholeStr := padright(copy(TempStr,1,pred(P)),WholeP,Pad);
  296.                DPStr := padleft(copy(TempStr,succ(P),RealDP),RealDP,Pad);
  297.             end;
  298.          end;
  299.          {now do something with the cursor!!}
  300.          StrLocX := 1;
  301.          GotoXY(X1+pred(StrLocX),Y1);
  302.       end;
  303. end; {FixedRefresh}
  304.  
  305. procedure FixedUpdate(FSP:FieldSettingsPtr);
  306. {}
  307. var ValStr: string;
  308. begin
  309.    if (FSP <> nil) then
  310.       with FSP^ do
  311.       with FixedInfoPtr(DataPtr)^ do
  312.       begin
  313.          ValStr := FixedValStr(FSP);
  314.          if ValidReal(ValStr) then
  315.             RPtr^ := StrToReal(ValStr)
  316.          else
  317.             RPtr^ := 0.0;
  318.       end;
  319. end; { FixedUpdate }
  320.  
  321. function FixedSuspend:boolean;
  322. {Checks for Min and Max and null}
  323. var
  324.   VR: extended;
  325.   FSP:FieldSettingsPtr;
  326.  
  327. begin
  328.    FSP := ActiveForm^.ActiveFieldPtr^.FieldInfo;
  329.    with FSP^ do
  330.    with FixedInfoPtr(DataPtr)^ do
  331.    begin
  332.       FixedSuspend := true;
  333.       Condense(FSP);
  334.       if (WholeStr = '') and (DPStr = '') then
  335.       begin
  336.          if not IsRule(FieldRules,AllowNull) then
  337.          begin
  338.             {Not empty message}
  339.             FixedSuspend := false;
  340.          end;
  341.          exit;
  342.       end
  343.       else
  344.       begin
  345.          if (EMin <> EMax) then  {need to check range}
  346.          begin
  347.             VR := StrToReal(strip('A',Pad,WholeStr+'.'+DPStr));
  348.             if (VR < EMin) or (VR > EMax) then
  349.             begin
  350.                OutOfRangeMessage(RealToStr(EMin,RealDP),RealToStr(EMax,RealDP));
  351.                FixedSuspend := false;
  352.             end;
  353.          end;
  354.       end;
  355.    end;
  356. end; { FixedSuspend }
  357.  
  358. procedure FixedDisplay(FSP:FieldSettingsPtr;Status:gStatus);
  359. {}
  360. begin
  361.    FixedRedisplay(FSP,Status);
  362. end; { FixedDisplay }
  363.  
  364. function FixedKeyHandler(InKey:word;X,Y:byte):gAction;
  365. {Input handler used by the lateral scrolling string field}
  366. var
  367.   FSP:FieldSettingsPtr;
  368.  
  369.    procedure Erase;
  370.    {}
  371.    begin
  372.       FixedSetNull(FSP);
  373.       FixedDisplay(FSP,HiStatus);
  374.    end; { Erase }
  375.  
  376.    procedure CursorRight;
  377.    {}
  378.    begin
  379.       with FSP^ do
  380.       with FixedInfoPtr(DataPtr)^ do
  381.       begin
  382.          if StrLocX < Fieldlen then
  383.             inc(StrLocX);
  384.          if (StrLocX = succ(WholeP)) then
  385.             inc(StrLocX);
  386.       end;
  387.    end; { CursorRight }
  388.  
  389.    procedure CursorLeft;
  390.    {}
  391.    begin
  392.       with FSP^ do
  393.       with FixedInfoPtr(DataPtr)^ do
  394.       begin
  395.          if StrLocX > 1 then
  396.             dec(StrLocX);
  397.          if (StrLocX = succ(WholeP)) then
  398.             dec(StrLocX);
  399.       end;
  400.    end; { CursorLeft }
  401.  
  402.    procedure CursorHome;
  403.    {}
  404.    begin
  405.       with FSP^ do
  406.       with FixedInfoPtr(DataPtr)^ do
  407.           StrLocX := 1;
  408.    end; { CursorHome }
  409.  
  410.    procedure CursorEnd;
  411.    {}
  412.    begin
  413.       with FSP^ do
  414.       with FixedInfoPtr(DataPtr)^ do
  415.           StrLocX := FieldLen;
  416.    end; { CursorEnd }
  417.  
  418.    procedure DeleteChar;
  419.    {}
  420.    var P : byte;
  421.    begin
  422.       with FSP^ do
  423.       with FixedInfoPtr(DataPtr)^ do
  424.       begin
  425.           if StrLocX  <= WholeP then
  426.           begin
  427.              P := StrLocX-(WholeP-length(WholeStr));
  428.              delete(WholeStr,P,1);
  429.              insert(Pad,WholeStr,P);
  430.           end
  431.           else
  432.           begin
  433.              P := StrLocX - succ(WholeP);
  434.              delete(DPStr,P,1);
  435.              insert(Pad,DPStr,P);
  436.           end;
  437.           FixedRedisplay(FSP,HiStatus);
  438.       end;
  439.    end; { DeleteChar }
  440.  
  441.    procedure Backspace;
  442.    {}
  443.    begin
  444.       with FSP^ do
  445.       with FixedInfoPtr(DataPtr)^ do
  446.       begin
  447.          if StrLocX > 1 then
  448.          begin
  449.             CursorLeft;
  450.             DeleteChar;
  451.          end;
  452.       end;
  453.    end; { Backspace }
  454.  
  455.    procedure PeriodHit;
  456.    {}
  457.    begin
  458.       with FSP^ do
  459.       with FixedInfoPtr(DataPtr)^ do
  460.       begin
  461.          Condense(FSP);
  462.          if RealDP > 0 then
  463.             StrLocX := WholeP + 2
  464.          else
  465.             StrLocX := WholeP;
  466.          FixedRedisplay(FSP,HiStatus);
  467.       end;
  468.    end; { PeriodHit }
  469.  
  470.    procedure PlusHit;
  471.    {}
  472.    var P: byte;
  473.    begin
  474.       with FSP^ do
  475.       with FixedInfoPtr(DataPtr)^ do
  476.       begin
  477.          if FirstCharPress and IsRule(FieldRules,EraseDefault) then
  478.             Erase;
  479.          P := pos('-',WholeStr);
  480.          if P > 0 then
  481.          begin
  482.             delete(WholeStr,P,1);
  483.             insert(Pad,WholeStr,P);
  484.             FixedRedisplay(FSP,HiStatus);
  485.          end;
  486.       end;
  487.    end; { PlusHit }
  488.  
  489.    procedure MinusHit;
  490.    {}
  491.    var P: byte;
  492.    begin
  493.       with FSP^ do
  494.       with FixedInfoPtr(DataPtr)^ do
  495.       begin
  496.          if (EMin >= 0.0) and (EMin <> EMax) then
  497.             Beep
  498.          else
  499.          begin
  500.             if FirstCharPress and IsRule(FieldRules,EraseDefault) then
  501.                Erase;
  502.             P := pos('-',WholeStr);
  503.             if P = 0 then
  504.             begin
  505.                P := pos(Pad,WholeStr);
  506.                if P = 0 then
  507.                   Beep
  508.                else
  509.                begin
  510.                   delete(WholeStr,P,1);
  511.                   WholeStr := '-'+WholeStr;
  512.                end;
  513.                FixedRedisplay(FSP,HiStatus);
  514.                if StrLocX = 1 then
  515.                   CursorRight;
  516.             end;
  517.          end;
  518.       end;
  519.    end; { MinusHit }
  520.  
  521.    procedure FixedProcessChar(FSP:FieldSettingsPtr; Ch:Char);
  522.    {}
  523.    var
  524.      P,WholePos,DPPos: byte;
  525.    begin
  526.       with FSP^ do
  527.       with FixedInfoPtr(DataPtr)^ do
  528.       begin
  529.          if Ch in ['0'..'9'] then
  530.          begin
  531.             if FirstCharPress and IsRule(FieldRules,EraseDefault) then
  532.             begin
  533.                FixedSetNull(FSP);
  534.                FixedRedisplay(FSP,HiStatus);
  535.             end;
  536.          end
  537.          else
  538.          begin
  539.             Ding;
  540.             exit
  541.          end;
  542.          WholePos := StrLocX-(WholeP-length(WholeStr));
  543.          if StrLocX > WholeP then  {entering decimals}
  544.             DPPos := StrLocX - succ(WholeP)
  545.          else
  546.             DPPos := 0;
  547.          if not ActiveForm^.InsertMode then
  548.          begin
  549.             if DPpos > 0 then  {entering decimals}
  550.             begin
  551.                delete(DPStr,DPPos,1);
  552.                insert(Ch,DPStr,DPPos);
  553.             end
  554.             else  {entering whole numbers}
  555.             begin
  556.                delete(WholeStr,WholePos,1);
  557.                insert(Ch,WholeStr,WholePos);
  558.             end;
  559.          end
  560.          else    {insertmode}
  561.          begin
  562.             if DPPos > 0 then  {entering decimals}
  563.             begin
  564.                if DPStr[DPPos] = Pad then
  565.                begin
  566.                   delete(DPStr,DPPos,1);
  567.                   insert(Ch,DPStr,DPPos);
  568.                end
  569.                else
  570.                begin
  571.                   P := PosAfter(Pad,DPStr,DPPos);
  572.                   if P = 0 then   {push a character off the end}
  573.                      delete(DPStr,length(DPStr),1)
  574.                   else
  575.                      delete(DPStr,P,1);
  576.                   insert(Ch,DPStr,DPPos);
  577.                end;
  578.             end
  579.             else  {entering whole numbers}
  580.             begin
  581.                if WholeStr[WholePos] in [Pad,'-'] then
  582.                begin
  583.                   delete(WholeStr,WholePos,1);
  584.                   insert(Ch,WholeStr,WholePos);
  585.                end
  586.                else
  587.                begin
  588.                   P := LastPosBefore(Pad,WholeStr,WholePos);
  589.                   if P = 0 then
  590.                      P := pos(Pad,WholeStr);
  591.                   if P = 0 then   {no room for another character}
  592.                   begin
  593.                      FieldFullMessage;
  594.                      exit;
  595.                   end
  596.                   else
  597.                   begin
  598.                      delete(WholeStr,P,1);
  599.                      insert(Ch,WholeStr,WholePos);
  600.                      if WholePos = WholeP then
  601.                      begin
  602.                         FixedRedisplay(FSP,HiStatus);  {don't cursor right}
  603.                         exit;
  604.                      end;
  605.                   end;
  606.                end;
  607.             end;
  608.          end;
  609.       end;
  610.       CursorRight;
  611.       FixedRedisplay(FSP,HiStatus);
  612.    end; { FixedProcessChar }
  613.  
  614.    procedure MouseDown;
  615.    {}
  616.    var
  617.       L,C,R:boolean;
  618.       X,Y:byte;
  619.    begin
  620.       with FSP^ do
  621.       with ScrollInfoPtr(DataPtr)^ do
  622.       begin
  623.          repeat
  624.             MouseStatusWin(L,C,R,X,Y);
  625.             if L and (Y = Y1) and (X >= X1) and (X <= X2) then
  626.             begin
  627.                StrLocX := X - pred(X1);
  628.                gotoxy(X,Y1);
  629.                if (FirstCharPress) then
  630.                begin  {clear the erase default setting}
  631.                    FirstCharPress := false;
  632.                    FixedRedisplay(FSP,HiStatus);
  633.                end;
  634.             end;
  635.          until not L;
  636.       end;
  637.    end; { MouseDown }
  638.  
  639. begin
  640.    FSP := ActiveForm^.ActiveFieldPtr^.FieldInfo;
  641.    FixedKeyHandler := none;
  642.    if Inkey = ord(DecimalSep) then
  643.       PeriodHit
  644.    else
  645.       case InKey of
  646.          8: BackSpace;
  647.          339: DeleteChar;
  648.          327: CursorHome;
  649.          335: CursorEnd;
  650.          331: CursorLeft;
  651.          333: CursorRight;
  652.          338: with ActiveForm^ do
  653.               begin
  654.                   InsertMode := not InsertMode;
  655.                   InsertProc(InsertMode);
  656.               end;
  657.          ord('+'): PlusHit;
  658.          ord('-'): MinusHit;
  659.          32..255: FixedProcessChar(FSP,chr(InKey));    {characters}
  660.          500: MouseDown;
  661.       end; {case}
  662.    if (Inkey > 0) and (Inkey < 256) then
  663.       FSP^.FirstCharPress := false;
  664.    with FSP^ do
  665.       GotoXY(X1+pred(StrLocX),Y1);
  666. end; { FixedKeyHandler }
  667.  
  668. procedure FixedDisposeHook(FNP:FieldSettingsPtr);
  669. {}
  670. begin
  671.    if FNP <> nil then
  672.       with FNP^ do
  673.          freemem(DataPtr,DataSize);
  674. end; {FixedDisposeHook}
  675. {$IFDEF FOFF}
  676.    {$F-}
  677.    {$UNDEF FOFF}
  678. {$ENDIF}
  679.  
  680. procedure FixedRealField(FieldID:integer; var Realvar:extended;Whole,DP:byte;Min,Max:extended);
  681. {}
  682. var FNP: FieldNodePtr;
  683. begin
  684.    FNP := FieldPtr(FieldID);
  685.    if (FNP <> nil) then
  686.       with FNP^.FieldInfo^ do
  687.       begin
  688.          RPtr := @RealVar;
  689.          RealDP := DP;
  690.          FieldType := IOOther;
  691.          FieldStr      := Sptr^;
  692.          if DP = 0 then
  693.             FieldLen := Whole
  694.          else
  695.             FieldLen      := succ(Whole+DP);
  696.          StrLocX       := 1;
  697.          X2 := X1 + pred(FieldLen);
  698.          ProcesskeyHook := FixedKeyHandler;
  699.          SuspendHook := FixedSuspend;
  700.          DisplayHook := FixedDisplay;
  701.          RefreshFieldHook := FixedRefresh;
  702.          UpdateVarHook := FixedUpdate;
  703.          DisposeHook := FixedDisposeHook;
  704.          OMisc       := FixedFld;
  705.          UsesCursors := false;
  706.          DataSize := sizeof(FixedInfo);
  707.          getmem(DataPtr,DataSize);
  708.          with FixedInfoPtr(DataPtr)^ do
  709.          begin
  710.             WholeP := Whole;
  711.             Pad := IOVars.Whitespace;
  712.             EMax := Max;
  713.             EMin := Min;
  714.          end;
  715.          FixedRefresh(FNP^.FieldInfo);
  716.       end;
  717. end; { FixedRealField }
  718.  
  719.                            {********************}
  720.                            {**  Spin Generic  **}
  721.                            {********************}
  722. procedure DrawIcons(X,Y:byte; Spinners, Drop:boolean; Active:boolean);
  723. {}
  724. var
  725.   W,BackAttr: byte;
  726.  
  727. begin
  728.    with IOVars.Form[IOVars.CurrentForm]^ do
  729.    with IO3Vars do
  730.    begin
  731.       BackAttr := BAttr(ReadAttr(X+1,Y));
  732.       if not Active then {hide icons}
  733.       begin
  734.          W := length(IconPadLeft)+length(IconPadRight)+1+ord(Drop)+Ord(Spinners);
  735.          WriteAT(succ(X),Y,Cattr(black,BackAttr),replicate(W,' '));
  736.       end
  737.       else
  738.       begin
  739.          if Spinners then
  740.          begin
  741.            if Drop then
  742.            begin
  743.               WriteAT(succ(X),Y,Cattr(BAttr(Col[IOIcons]),BackAttr),IconPadLeft+'   '+IconPadRight);
  744.               WriteAT(X+2,Y,Col[IOIcons],SpinDown+SpinUp+DropDown);
  745.            end
  746.            else
  747.            begin
  748.               WriteAT(succ(X),Y,Cattr(BAttr(Col[IOIcons]),BackAttr),IconPadLeft+'  '+IconPadRight);
  749.               WriteAT(X+2,Y,Col[IOIcons],SpinDown+SpinUp);
  750.            end;
  751.          end
  752.          else      {draw drop icon}
  753.          begin
  754.               WriteAT(succ(X),Y,Cattr(BAttr(Col[IOIcons]),BackAttr),IconPadLeft+' '+IconPadRight);
  755.               WriteAT(X+2,Y,Col[IOIcons],DropDown);
  756.          end;
  757.       end;
  758.    end;
  759. end; { DrawIcons }
  760.  
  761. {$IFOPT F-}
  762.    {$DEFINE FOFF}
  763.    {$F+}
  764. {$ENDIF}
  765. procedure SpinBasicDisplay(FSP:FieldSettingsPtr;Status:gStatus);
  766. {}
  767. begin
  768.    with FSP^ do
  769.    begin
  770.       DrawIcons(X2,Y1,true,false,Active=FldOn);
  771.       BasicDisplay(FSP,Status);
  772.    end;
  773. end; { SpinBasicDisplay }
  774. {$IFDEF FOFF}
  775.    {$F-}
  776.    {$UNDEF FOFF}
  777. {$ENDIF}
  778.  
  779.                              {****************}
  780.                              {**  SpinLong  **}
  781.                              {****************}
  782. {$IFOPT F-}
  783.    {$DEFINE FOFF}
  784.    {$F+}
  785. {$ENDIF}
  786. function SpinLongKeyHandler(InKey:word;X,Y:byte):gAction;
  787. {Input handler used by the lateral scrolling string field}
  788. var
  789.   FSP:FieldSettingsPtr;
  790.   WaitTime,
  791.   RetCode:integer;
  792.   VL:longint;
  793.   L,C,R: boolean;
  794.   MX,MY: byte;
  795.  
  796.    procedure SpinUpOne;
  797.    {}
  798.    begin
  799.       with FSP^ do
  800.       begin
  801.          val(FieldStr,VL,Retcode);
  802.          if (RetCode = 0) and ((LMin = LMax) or (VL < LMax)) then
  803.          begin
  804.             FieldStr := IntToStr(VL+delta);
  805.             SetCursor(FSP);
  806.          end;
  807.       end;
  808.    end; { SpinUpOne }
  809.  
  810.    procedure SpinDownOne;
  811.    {}
  812.    begin
  813.       with FSP^ do
  814.       begin
  815.          val(FieldStr,VL,Retcode);
  816.          if (RetCode = 0) and ((LMin = LMax) or (VL > LMin)) then
  817.          begin
  818.             FieldStr := IntToStr(VL-Delta);
  819.             SetCursor(FSP);
  820.          end;
  821.       end;
  822.    end; { SpinDownOne }
  823.  
  824.    procedure MouseSpinUp;
  825.    {}
  826.    begin
  827.       WaitTime := KeyVars.InitScrollDelay;
  828.       with FSP^ do
  829.       begin
  830.          val(FieldStr,VL,Retcode);
  831.          if (RetCode = 0) then
  832.          begin
  833.             FirstCharPress := false;
  834.             repeat
  835.                MouseStatusWin(L,C,R,MX,MY);
  836.                if L and (MY = Y1) and (MX = X2+3) then
  837.                begin
  838.                   if ((LMin = LMax) or (VL < LMax)) then
  839.                   begin
  840.                      inc(VL,delta);
  841.                      FieldStr := IntToStr(VL);
  842.                      BasicDisplay(FSP,HiStatus);
  843.                      if (ActiveForm^.WinNum <> 0) then
  844.                         WinDrawTop;
  845.                   end;
  846.                end;
  847.                DelayIt(L,(ActiveForm^.WinNum <> 0),WaitTime);
  848.             until not L;
  849.          end
  850.          else
  851.             MouseRelease;
  852.       end;
  853.       SetCursor(FSP);
  854.    end; { MouseSpinUp }
  855.  
  856.    procedure MouseSpinDown;
  857.    {}
  858.    begin
  859.       WaitTime := KeyVars.InitScrollDelay;
  860.       with FSP^ do
  861.       begin
  862.          val(FieldStr,VL,Retcode);
  863.          if (RetCode = 0) then
  864.          begin
  865.             FirstCharPress := false;
  866.             repeat
  867.                MouseStatusWin(L,C,R,MX,MY);
  868.                if L and (MY = Y1) and (MX = X2+2) then
  869.                begin
  870.                   if ((LMin = LMax) or (VL > LMin)) then
  871.                   begin
  872.                      dec(VL,Delta);
  873.                      FieldStr := IntToStr(VL);
  874.                      BasicDisplay(FSP,HiStatus);
  875.                      if (ActiveForm^.WinNum <> 0) then
  876.                         WinDrawTop;
  877.                   end;
  878.                end;
  879.                DelayIt(L,(ActiveForm^.WinNum <> 0),WaitTime);
  880.             until not L;
  881.          end
  882.          else
  883.             MouseRelease;
  884.       end;
  885.       SetCursor(FSP);
  886.    end; { MouseSpinDown }
  887.  
  888. begin
  889.    FSP := ActiveForm^.ActiveFieldPtr^.FieldInfo;
  890.    SpinLongKeyHandler := none;
  891.    with FSP^ do
  892.    with IO3Vars do
  893.    begin
  894.       if (Inkey = SpinUpkey) then
  895.          SpinUpOne
  896.       else if (Inkey = SpinDownkey) then
  897.          SpinDownOne
  898.       else if (Inkey = 500) and (X = X2+2) then
  899.          MouseSpinDown
  900.       else if (Inkey = 500) and (X = X2+3) then
  901.          MouseSpinUp
  902.       else
  903.          SpinLongKeyHandler := BasicKeyHandler(Inkey,X,Y);
  904.    end; {with}
  905. end; { SpinLongKeyHandler }
  906. {$IFDEF FOFF}
  907.    {$F-}
  908.    {$UNDEF FOFF}
  909. {$ENDIF}
  910.  
  911. procedure SpinLongField(FieldID:integer; var LongIntvar:LongInt;Width:byte;
  912.                         Min,Max,Increment : LongInt);
  913. {}
  914. var FNP: FieldNodePtr;
  915. begin
  916.    FNP := FieldPtr(FieldID);
  917.    if (FNP <> nil) then
  918.       with FNP^.FieldInfo^ do
  919.       begin
  920.          FieldType := IOLongInt;
  921.          LPtr      := @LongIntVar;
  922.          FieldFmt  := replicate(Width,'#');
  923.          FieldStr  := VartoString(FieldID);
  924.          if (Max = 0) or (Max < Min) then
  925.             LMax := 2147483647
  926.          else
  927.             LMax := Max;
  928.          if ((Min = 0) and (Max = 0)) or (Min > LMax) then
  929.             LMin := -2147483647
  930.          else
  931.             LMin := Min;
  932.          if Increment < 1 then
  933.             Delta := 1
  934.          else
  935.             Delta := Increment;
  936.          FieldLen  := Width;
  937.          X2 := X1 + pred(FieldLen);
  938.          IconWidth := 4;
  939.          SetBasicHooks(FNP^.FieldInfo,true);
  940.          DisplayHook := SpinBasicDisplay;
  941.          ProcesskeyHook := SpinLongKeyHandler;
  942.        end;
  943. end; {SpinLongField}
  944.  
  945.                              {****************}
  946.                              {**  SpinReal  **}
  947.                              {****************}
  948. {$IFOPT F-}
  949.    {$DEFINE FOFF}
  950.    {$F+}
  951. {$ENDIF}
  952. procedure SpinRealDisplay(FSP:FieldSettingsPtr;Status:gStatus);
  953. {}
  954. begin
  955.    with FSP^ do
  956.    begin
  957.       DrawIcons(X2,Y1,true,false,Active=FldOn);
  958.       FixedDisplay(FSP,Status);
  959.    end;
  960. end; { SpinRealDisplay }
  961.  
  962. function SpinRealKeyHandler(InKey:word;X,Y:byte):gAction;
  963. {Input handler used by the lateral scrolling string field}
  964. var
  965.    FSP:FieldSettingsPtr;
  966.    WaitTime:integer;
  967.    VE:extended;
  968.    L,C,R: boolean;
  969.    MX,MY: byte;
  970.  
  971.    procedure SpinUpDelta;
  972.    {}
  973.    begin
  974.       with FSP^ do
  975.       with FixedInfoPtr(DataPtr)^ do
  976.       begin
  977.          VE := StrToReal(FixedValStr(FSP));
  978.          if ((EMin = EMax) or (VE < EMax)) then
  979.          begin
  980.             VE := VE + EDelta;
  981.             if VE > EMax then
  982.                VE := EMax;
  983.             RPtr^ := VE;
  984.             FixedRefresh(FSP);
  985.          end;
  986.       end;
  987.    end; { SpinUpDelta }
  988.  
  989.    procedure SpinDownDelta;
  990.    {}
  991.    begin
  992.       with FSP^ do
  993.       with FixedInfoPtr(DataPtr)^ do
  994.       begin
  995.          VE := StrToReal(FixedValStr(FSP));
  996.          if ((EMin = EMax) or (VE > EMin)) then
  997.          begin
  998.             VE := VE - EDelta;
  999.             if VE < EMin then
  1000.                VE := EMin;
  1001.             RPtr^ := VE;
  1002.             FixedRefresh(FSP);
  1003.          end;
  1004.       end;
  1005.    end; { SpinDownDelta }
  1006.  
  1007.    procedure MouseSpinUp;
  1008.    {}
  1009.    begin
  1010.       WaitTime := KeyVars.InitScrollDelay;
  1011.       with FSP^ do
  1012.       with FixedInfoPtr(DataPtr)^ do
  1013.       begin
  1014.          VE := StrToReal(FixedValStr(FSP));
  1015.          FirstCharPress := false;
  1016.          repeat
  1017.             MouseStatusWin(L,C,R,MX,MY);
  1018.             if L and (MY = Y1) and (MX = X2+3) then
  1019.             begin
  1020.                if ((EMin = EMax) or (VE < EMax)) then
  1021.                begin
  1022.                   VE := VE + EDelta;
  1023.                   if VE > EMax then
  1024.                      VE := EMax;
  1025.                   RPtr^ := VE;
  1026.                   FixedRefresh(FSP);
  1027.                   FixedDisplay(FSP,HiStatus);
  1028.                   if (ActiveForm^.WinNum <> 0) then
  1029.                      WinDrawTop;
  1030.                end;
  1031.                DelayIt(L,(ActiveForm^.WinNum <> 0),WaitTime);
  1032.             end;
  1033.          until not L;
  1034.       end;
  1035.       SetCursor(FSP);
  1036.    end; { MouseSpinUp }
  1037.  
  1038.    procedure MouseSpinDown;
  1039.    {}
  1040.    begin
  1041.       WaitTime := KeyVars.InitScrollDelay;
  1042.       with FSP^ do
  1043.       with FixedInfoPtr(DataPtr)^ do
  1044.       begin
  1045.          VE := StrToReal(FixedValStr(FSP));
  1046.          FirstCharPress := false;
  1047.          repeat
  1048.             MouseStatusWin(L,C,R,MX,MY);
  1049.             if L and (MY = Y1) and (MX = X2+2) then
  1050.             begin
  1051.                if ((EMin = EMax) or (VE > EMin)) then
  1052.                begin
  1053.                   VE := VE - EDelta;
  1054.                   if VE < EMin then
  1055.                      VE := EMin;
  1056.                   RPtr^ := VE;
  1057.                   FixedRefresh(FSP);
  1058.                   FixedDisplay(FSP,HiStatus);
  1059.                   if (ActiveForm^.WinNum <> 0) then
  1060.                      WinDrawTop;
  1061.                end;
  1062.                DelayIt(L,(ActiveForm^.WinNum <> 0),WaitTime);
  1063.             end;
  1064.          until not L;
  1065.       end;
  1066.       SetCursor(FSP);
  1067.    end; { MouseSpinDown }
  1068.  
  1069. begin
  1070.    FSP := ActiveForm^.ActiveFieldPtr^.FieldInfo;
  1071.    SpinRealKeyHandler := none;
  1072.    with FSP^ do
  1073.    with IO3Vars do
  1074.    begin
  1075.       if (Inkey = SpinUpkey) then
  1076.          SpinUpDelta
  1077.       else if (Inkey = SpinDownkey) then
  1078.          SpinDownDelta
  1079.       else if (Inkey = 500) and (X = X2+2) then
  1080.          MouseSpinDown
  1081.       else if (Inkey = 500) and (X = X2+3) then
  1082.          MouseSpinUp
  1083.       else
  1084.          SpinRealKeyHandler := FixedKeyHandler(Inkey,X,Y);
  1085.    end; {with}
  1086. end; { SpinRealKeyHandler }
  1087. {$IFDEF FOFF}
  1088.    {$F-}
  1089.    {$UNDEF FOFF}
  1090. {$ENDIF}
  1091.  
  1092. procedure SpinRealField(FieldID:integer; var Realvar:extended;Whole,DP:byte;Min,Max,Delta:extended);
  1093. {}
  1094. var FNP: FieldNodePtr;
  1095. begin
  1096.    FNP := FieldPtr(FieldID);
  1097.    if (FNP <> nil) then
  1098.       with FNP^.FieldInfo^ do
  1099.       begin
  1100.          FixedRealField(FieldID,Realvar,Whole,DP,Min,Max);
  1101.          IconWidth := 4;
  1102.          FixedInfoPtr(DataPtr)^.EDelta := Delta;
  1103.          DisplayHook := SpinRealDisplay;
  1104.          ProcesskeyHook := SpinRealKeyHandler;
  1105.        end;
  1106. end; {SpinRealField}
  1107.  
  1108.                              {****************}
  1109.                              {**  SpinDate  **}
  1110.                              {****************}
  1111.  
  1112. {$IFOPT F-}
  1113.    {$DEFINE FOFF}
  1114.    {$F+}
  1115. {$ENDIF}
  1116. function SpinDateKeyHandler(InKey:word;X,Y:byte):gAction;
  1117. var
  1118.   FSP:FieldSettingsPtr;
  1119.   WaitTime: integer;
  1120.   Jul:dates;
  1121.   L,C,R: boolean;
  1122.   MX,MY: byte;
  1123.  
  1124.    procedure SpinUpOne;
  1125.    {}
  1126.    begin
  1127.       with FSP^ do
  1128.       begin
  1129.          if not ValidDateStr(FieldStr,DFormat) then
  1130.             exit;
  1131.          Jul := StrtoJul(FieldStr,DFormat);
  1132.          if (DMin = DMax) or (Jul < DMax) then
  1133.          begin
  1134.             FieldStr:= Unformatteddate(JultoStr(succ(Jul),DFormat));
  1135.             SetCursor(FSP);
  1136.          end;
  1137.       end;
  1138.    end; { SpinUpOne }
  1139.  
  1140.    procedure SpinDownOne;
  1141.    {}
  1142.    begin
  1143.       with FSP^ do
  1144.       begin
  1145.          if not ValidDateStr(FieldStr,DFormat) then
  1146.             exit;
  1147.          Jul := StrtoJul(FieldStr,DFormat);
  1148.          if (DMin = DMax) or (Jul > DMin) then
  1149.          begin
  1150.             FieldStr:= Unformatteddate(JultoStr(pred(Jul),DFormat));
  1151.             SetCursor(FSP);
  1152.          end;
  1153.       end;
  1154.    end; { SpinDownOne }
  1155.  
  1156.    procedure MouseSpinUp;
  1157.    {}
  1158.    begin
  1159.       WaitTime := KeyVars.InitScrollDelay;
  1160.       with FSP^ do
  1161.       begin
  1162.          if ValidDateStr(FieldStr,DFormat) then
  1163.          begin
  1164.             FirstCharPress := false;
  1165.             Jul := StrtoJul(FieldStr,DFormat);
  1166.             repeat
  1167.                MouseStatusWin(L,C,R,MX,MY);
  1168.                if L and (MY = Y1) and (MX = X2+3) then
  1169.                begin
  1170.                   if (DMin = DMax) or (Jul < DMax) then
  1171.                   begin
  1172.                      inc(Jul);
  1173.                      FieldStr:= Unformatteddate(JultoStr(Jul,DFormat));
  1174.                      BasicDisplay(FSP,HiStatus);
  1175.                      if (ActiveForm^.WinNum <> 0) then
  1176.                         WinDrawTop;
  1177.                   end;
  1178.                end;
  1179.                DelayIt(L,(ActiveForm^.WinNum <> 0),WaitTime);
  1180.             until not L;
  1181.          end
  1182.          else
  1183.             MouseRelease;
  1184.       end;
  1185.       SetCursor(FSP);
  1186.    end; { MouseSpinUp }
  1187.  
  1188.    procedure MouseSpinDown;
  1189.    {}
  1190.    begin
  1191.       WaitTime := KeyVars.InitScrollDelay;
  1192.       with FSP^ do
  1193.       begin
  1194.          if ValidDateStr(FieldStr,DFormat) then
  1195.          begin
  1196.             FirstCharPress := false;
  1197.             Jul := StrtoJul(FieldStr,DFormat);
  1198.             repeat
  1199.                MouseStatusWin(L,C,R,MX,MY);
  1200.                if L and (MY = Y1) and (MX = X2+2) then
  1201.                begin
  1202.                   if ((DMin = DMax) or (Jul > DMin)) then
  1203.                   begin
  1204.                      dec(Jul);
  1205.                      FieldStr:= Unformatteddate(JultoStr(Jul,DFormat));
  1206.                      BasicDisplay(FSP,HiStatus);
  1207.                      if (ActiveForm^.WinNum <> 0) then
  1208.                         WinDrawTop;
  1209.                   end;
  1210.                end;
  1211.                DelayIt(L,(ActiveForm^.WinNum <> 0),WaitTime);
  1212.             until not L;
  1213.          end
  1214.          else
  1215.             MouseRelease;
  1216.       end;
  1217.       SetCursor(FSP);
  1218.    end; { MouseSpinDown }
  1219.  
  1220. begin
  1221.    FSP := ActiveForm^.ActiveFieldPtr^.FieldInfo;
  1222.    SpinDateKeyHandler := none;
  1223.    with FSP^ do
  1224.    with IO3Vars do
  1225.    begin
  1226.       if (Inkey = SpinUpkey) then
  1227.          SpinUpOne
  1228.       else if (Inkey = SpinDownkey) then
  1229.          SpinDownOne
  1230.       else if (Inkey = 500) and (X = X2+2) then
  1231.          MouseSpinDown
  1232.       else if (Inkey = 500) and (X = X2+3) then
  1233.          MouseSpinUp
  1234.       else
  1235.          SpinDateKeyHandler := BasicKeyHandler(Inkey,X,Y);
  1236.    end; {with}
  1237. end; { SpinDateKeyHandler }
  1238. {$IFDEF FOFF}
  1239.    {$F-}
  1240.    {$UNDEF FOFF}
  1241. {$ENDIF}
  1242.  
  1243. procedure SpinDateField(FieldID:integer; var Datevar:Dates; DateFormat:gDate;
  1244.                         DefFormat:string; Min,Max : Dates);
  1245. {}
  1246. var FNP: FieldNodePtr;
  1247. begin
  1248.    FNP := FieldPtr(FieldID);
  1249.    if (FNP <> nil) then
  1250.       with FNP^.FieldInfo^ do
  1251.       begin
  1252.          DateField(FieldID,Datevar,DateFormat,DefFormat,Min,Max);
  1253.          IconWidth := 4;
  1254.          DisplayHook := SpinBasicDisplay;
  1255.          ProcesskeyHook := SpinDateKeyHandler;
  1256.        end;
  1257. end; {SpinDateField}
  1258.  
  1259.                              {****************}
  1260.                              {**  DropDate  **}
  1261.                              {****************}
  1262.  
  1263. procedure DropTheCal(FSP:FieldSettingsPtr);
  1264. {}
  1265. var
  1266.   Jul: Dates;
  1267.   OldSettings: CalSet;
  1268. begin
  1269.    with FSP^ do
  1270.    begin
  1271.       OldSettings := CalVars;
  1272.       {adjust the calendar window position}
  1273.       with CalVars do
  1274.       begin
  1275.  
  1276.       end;
  1277.       Jul := StrtoJul(FieldStr,DFormat);
  1278.       if (FieldStr = '') or (Jul = 0) then
  1279.          Jul := TodayinJul;
  1280.       CalVars.Chooseday := true;
  1281.       Jul := RunCalendar(Jul,'');
  1282.       if (KeyVars.LastKey <> 27) and (KeyVars.LastKey <> 600) then
  1283.          FieldStr:= Unformatteddate(JultoStr(Jul,DFormat));
  1284.    end;
  1285.    CalVars := OldSettings;
  1286. end; { DropTheCal }
  1287.  
  1288. function ReleaseOnDrop(FSP:FieldSettingsPtr;X2Offset:byte):boolean;
  1289. {}
  1290. var
  1291.   L,C,R: boolean;
  1292.   X,Y: byte;
  1293. begin
  1294.    repeat
  1295.       MouseStatusWin(L,C,R,X,Y);
  1296.    until not L;
  1297.    with FSP^ do
  1298.       ReleaseOnDrop := (Y = Y1) and (X = X2 + X2Offset);
  1299. end; { ReleaseOnDrop }
  1300.  
  1301. {$IFOPT F-}
  1302.    {$DEFINE FOFF}
  1303.    {$F+}
  1304. {$ENDIF}
  1305. procedure DropDateDisplay(FSP:FieldSettingsPtr;Status:gStatus);
  1306. {}
  1307. begin
  1308.    with FSP^ do
  1309.    begin
  1310.       DrawIcons(X2,Y1,false,true,Active=FldOn);
  1311.       BasicDisplay(FSP,Status);
  1312.    end;
  1313. end; { DropDateDisplay }
  1314.  
  1315. function DropDateKeyHandler(InKey:word;X,Y:byte):gAction;
  1316. var
  1317.   FSP:FieldSettingsPtr;
  1318. begin
  1319.    FSP := ActiveForm^.ActiveFieldPtr^.FieldInfo;
  1320.    DropDateKeyHandler := none;
  1321.    with FSP^ do
  1322.    with IO3Vars do
  1323.    begin
  1324.       if (InKey = DropDownKey) then
  1325.          DropTheCal(FSP)
  1326.       else if ((Inkey=500) and (X = X2+2)) then
  1327.       begin
  1328.          if ReleaseOnDrop(FSP,2) then
  1329.              DropTheCal(FSP);
  1330.       end
  1331.       else
  1332.          DropDateKeyHandler := BasicKeyHandler(Inkey,X,Y);
  1333.    end;
  1334. end; { DropDateKeyHandler }
  1335. {$IFDEF FOFF}
  1336.    {$F-}
  1337.    {$UNDEF FOFF}
  1338. {$ENDIF}
  1339.  
  1340. procedure DropDateField(FieldID:integer; var Datevar:Dates; DateFormat:gDate;
  1341.                         DefFormat:string; Min,Max : Dates);
  1342. {}
  1343. var FNP: FieldNodePtr;
  1344. begin
  1345.    FNP := FieldPtr(FieldID);
  1346.    if (FNP <> nil) then
  1347.       with FNP^.FieldInfo^ do
  1348.       begin
  1349.          DateField(FieldID,Datevar,DateFormat,DefFormat,Min,Max);
  1350.          IconWidth := 4;
  1351.          DisplayHook := DropDateDisplay;
  1352.          ProcesskeyHook := DropDateKeyHandler;
  1353.          UsesCursors := true;
  1354.        end;
  1355. end; {DropDateField}
  1356.  
  1357.                            {********************}
  1358.                            {**  SpinDropDate  **}
  1359.                            {********************}
  1360.  
  1361. {$IFOPT F-}
  1362.    {$DEFINE FOFF}
  1363.    {$F+}
  1364. {$ENDIF}
  1365. procedure SpinDropDateDisplay(FSP:FieldSettingsPtr;Status:gStatus);
  1366. {}
  1367. begin
  1368.    with FSP^ do
  1369.    begin
  1370.       DrawIcons(X2,Y1,true,true,Active=FldOn);
  1371.       BasicDisplay(FSP,Status);
  1372.    end;
  1373. end; { SpinDropDateDisplay }
  1374.  
  1375. function SpinDropDateKeyHandler(InKey:word;X,Y:byte):gAction;
  1376. var
  1377.   FSP:FieldSettingsPtr;
  1378. begin
  1379.    FSP := ActiveForm^.ActiveFieldPtr^.FieldInfo;
  1380.    SpinDropDateKeyHandler := none;
  1381.    with FSP^ do
  1382.    with IO3Vars do
  1383.    begin
  1384.       if (InKey = DropDownKey) then
  1385.          DropTheCal(FSP)
  1386.       else if ((Inkey=500) and (X = X2+4)) then
  1387.       begin
  1388.          if ReleaseOnDrop(FSP,4) then
  1389.             DropTheCal(FSP);
  1390.       end
  1391.       else
  1392.          SpinDropDateKeyHandler := SpinDateKeyHandler(Inkey,X,Y);
  1393.    end;
  1394. end; { SpinDropDateKeyHandler }
  1395. {$IFDEF FOFF}
  1396.    {$F-}
  1397.    {$UNDEF FOFF}
  1398. {$ENDIF}
  1399.  
  1400. procedure SpinDropDateField(FieldID:integer; var Datevar:Dates; DateFormat:gDate;
  1401.                             DefFormat:string; Min,Max : Dates);
  1402. {}
  1403. var FNP: FieldNodePtr;
  1404. begin
  1405.    FNP := FieldPtr(FieldID);
  1406.    if (FNP <> nil) then
  1407.       with FNP^.FieldInfo^ do
  1408.       begin
  1409.          DateField(FieldID,Datevar,DateFormat,DefFormat,Min,Max);
  1410.          IconWidth := 5;
  1411.          DisplayHook := SpinDropDateDisplay;
  1412.          ProcesskeyHook := SpinDropDateKeyHandler;
  1413.          UsesCursors := true;
  1414.        end;
  1415. end; {SpinDropDateField}
  1416.  
  1417.                             {*****************}
  1418.                             {**  Drop List  **}
  1419.                             {*****************}
  1420.  
  1421. function DropTheList(FSP:FieldSettingsPtr): longint;
  1422. {}
  1423. var
  1424.   X,Y,
  1425.   W,D: byte;
  1426. begin
  1427.    with FSP^ do
  1428.    with ListCfg(DataPtr^)  do
  1429.    begin
  1430.       W := X2-X1+6;                                 {make window correct width}
  1431.       if StringLLPtr(DataSource)^.TotalNodes <= 8 then
  1432.          D := StringLLPtr(DataSource)^.TotalNodes + 2
  1433.       else
  1434.          D := 10;
  1435.       if (ActiveForm^.WinNum <> 0) then
  1436.       begin
  1437.          X := WinGlobalX(0,X1);
  1438.          Y := WinGlobalY(0,Y1);
  1439.       end
  1440.       else
  1441.       begin
  1442.          X := X1;
  1443.          Y := Y1;
  1444.       end;
  1445.       {display the window over the field if it fits}
  1446.       with ListVars do
  1447.       begin
  1448.          if X + W - 2 <= HardVars.Width then
  1449.          begin
  1450.             if X > 2 then
  1451.                ListVars.WX1 := X - 2
  1452.             else
  1453.                ListVars.WX1 := 1;
  1454.          end
  1455.          else if HardVars.Width - W - 4 >= 1 then
  1456.             ListVars.WX1 := HardVars.Width - W - 4
  1457.          else
  1458.             ListVars.WX1 := 1;
  1459.          if Y + D - 1 <= HardVars.Depth then
  1460.          begin
  1461.             if Y > 1 then
  1462.                ListVars.WY1 := pred(Y)
  1463.             else
  1464.                Y := 1;
  1465.          end
  1466.          else if HardVars.Depth - D - 2 >= 1 then
  1467.             ListVars.WY1 := HardVars.Depth - D
  1468.          else
  1469.             ListVars.WY1 := 1;
  1470.          WX2 := WX1 + pred(W);
  1471.          WY2 := WY1 + pred(D);
  1472.       end;
  1473.       {show the list}
  1474.       DropTheList := RunListStrLL(StringLLPtr(DataSource)^,'');
  1475.    end;
  1476. end; { DropTheList }
  1477.  
  1478. procedure JustDropList(FSP:FieldSettingsPtr);
  1479. {}
  1480. var Item: longint;
  1481. begin
  1482.    Item := DropTheList(FSP);
  1483.    {update the field if the user didn't escape}
  1484.    if Item <> 0 then
  1485.       with FSP^ do
  1486.       with StringLLPtr(ListCfg(DataPtr^).DataSource)^  do
  1487.            ActiveNode := Item
  1488. end; { JustDropList }
  1489.  
  1490. procedure DropListRedisplay(FSP:FieldSettingsPtr;Status:gStatus);
  1491. {}
  1492. var A : byte;
  1493. begin
  1494.    with FSP^ do
  1495.    with ListCfg(DataPtr^)  do
  1496.    with IOVars.Form[IOVars.CurrentForm]^ do
  1497.    begin
  1498.       if Active <> FldOn then
  1499.          A := Col[IOEditOff]
  1500.       else
  1501.       case Status of
  1502.          NormStatus: A := Col[IOEditNorm];
  1503.          OffStatus:  A := Col[IOEditOff];
  1504.          else A := Col[IOEditHi];
  1505.       end;
  1506.       WriteAT(X1,Y1,A,padleft(StrLLGetStr(StringLLPtr(DataSource)^,
  1507.                               StringLLPtr(DataSource)^.ActiveNode),
  1508.                               succ(X2-X1),' '));
  1509.       integer(SourcePtr^) := ActiveNode;
  1510.       if Status in [HiStatus,Activate] then
  1511.          GotoXY(X1,Y1);
  1512.    end;
  1513. end; {DropListRedisplay}
  1514.  
  1515.  
  1516. {$IFOPT F-}
  1517.    {$DEFINE FOFF}
  1518.    {$F+}
  1519. {$ENDIF}
  1520. procedure DropListDisplay(FSP:FieldSettingsPtr;Status:gStatus);
  1521. {}
  1522. begin
  1523.    with FSP^ do
  1524.    begin
  1525.       DrawIcons(X2,Y1,false,true,Active=FldOn);
  1526.       DropListReDisplay(FSP,Status);
  1527.    end;
  1528. end; { DropListDisplay }
  1529.  
  1530. function DropListKeyHandler(InKey:word;X,Y:byte):gAction;
  1531. var
  1532.   FSP:FieldSettingsPtr;
  1533. begin
  1534.    FSP := ActiveForm^.ActiveFieldPtr^.FieldInfo;
  1535.    DropListKeyHandler := none;
  1536.    with FSP^ do
  1537.    with IO3Vars do
  1538.    begin
  1539.       if (InKey = DropDownKey) then
  1540.          JustDropList(FSP)
  1541.       else if ((Inkey=500) and (X = X2+2)) then
  1542.       begin
  1543.          if ReleaseOnDrop(FSP,2) then
  1544.             JustDropList(FSP);
  1545.       end
  1546.       else
  1547.          with StringLLPtr(ListCfg(DataPtr^).DataSource)^  do
  1548.          begin
  1549.            if (Inkey = SpinDownkey) and (ActiveNode < TotalNodes) then
  1550.                inc(ActiveNode)
  1551.            else if (Inkey = SpinUpkey) and (ActiveNode > 1) then
  1552.                dec(ActiveNode);
  1553.          end;
  1554.       ListCfg(DataPtr^).ActiveNode := StringLLPtr(ListCfg(DataPtr^).DataSource)^.ActiveNode;
  1555.       integer(SourcePtr^) := ListCfg(DataPtr^).ActiveNode;
  1556.    end;
  1557. end; { DropListKeyHandler }
  1558. {$IFDEF FOFF}
  1559.    {$F-}
  1560.    {$UNDEF FOFF}
  1561. {$ENDIF}
  1562.  
  1563. procedure DropListField(FieldID:integer; width:byte; var SelectedItem:integer);
  1564. {}
  1565. var FNP: FieldNodePtr;
  1566. begin
  1567.    FNP := FieldPtr(FieldID);
  1568.    if (FNP <> nil) then
  1569.       with FNP^.FieldInfo^ do
  1570.       begin
  1571.          ListField(FieldID,width,1,SelectedItem);
  1572.          ProcesskeyHook := DropListKeyHandler;
  1573.          DisplayHook := DropListDisplay;
  1574.          IconWidth := 4;
  1575.       end;
  1576. end; { DropListField }
  1577.  
  1578.                             {*****************}
  1579.                             {**  Spin List  **}
  1580.                             {*****************}
  1581.  
  1582. {$IFOPT F-}
  1583.    {$DEFINE FOFF}
  1584.    {$F+}
  1585. {$ENDIF}
  1586. procedure SpinListDisplay(FSP:FieldSettingsPtr;Status:gStatus);
  1587. {}
  1588. begin
  1589.    with FSP^ do
  1590.    begin
  1591.       DrawIcons(X2,Y1,true,false,Active=FldOn);
  1592.       DropListRedisplay(FSP,Status);
  1593.    end;
  1594. end; { SpinListDisplay }
  1595.  
  1596. function SpinListKeyHandler(InKey:word;X,Y:byte):gAction;
  1597. var
  1598.   FSP:FieldSettingsPtr;
  1599.   WaitTime: integer;
  1600.   L,C,R: boolean;
  1601.   MX,MY:byte;
  1602.  
  1603.    procedure SpinUpOne;
  1604.    {Spins down the list by increasing the ActiveNode value}
  1605.    begin
  1606.       with FSP^ do
  1607.       with StringLLPtr(ListCfg(DataPtr^).DataSource)^  do
  1608.       begin
  1609.          if ActiveNode < TotalNodes then
  1610.             inc(ActiveNode);
  1611.       end;
  1612.    end; { SpinUpOne }
  1613.  
  1614.    procedure SpinDownOne;
  1615.    {Spins up the list by decreasing the ActiveNode value}
  1616.    begin
  1617.       with FSP^ do
  1618.       with StringLLPtr(ListCfg(DataPtr^).DataSource)^ do
  1619.       begin
  1620.          if ActiveNode > 1 then
  1621.             dec(ActiveNode);
  1622.       end;
  1623.    end; { SpinDownOne }
  1624.  
  1625.    procedure MouseSpinUp;
  1626.    {}
  1627.    begin
  1628.       WaitTime := KeyVars.InitScrollDelay;
  1629.       with FSP^ do
  1630.       with StringLLPtr(ListCfg(DataPtr^).DataSource)^  do
  1631.       begin
  1632.             FirstCharPress := false;
  1633.             repeat
  1634.                MouseStatusWin(L,C,R,MX,MY);
  1635.                if L and (MY = Y1) and (MX = X2+3) then
  1636.                begin
  1637.                   if ActiveNode > 1 then
  1638.                   begin
  1639.                      dec(ActiveNode);
  1640.                      DropListRedisplay(FSP,HiStatus);
  1641.                      if (ActiveForm^.WinNum <> 0) then
  1642.                         WinDrawTop;
  1643.                   end;
  1644.                end;
  1645.                DelayIt(L,(ActiveForm^.WinNum <> 0),WaitTime);
  1646.             until not L;
  1647.       end;
  1648.    end; { MouseSpinUp }
  1649.  
  1650.    procedure MouseSpinDown;
  1651.    {}
  1652.    begin
  1653.       WaitTime := KeyVars.InitScrollDelay;
  1654.       with FSP^ do
  1655.       with StringLLPtr(ListCfg(DataPtr^).DataSource)^  do
  1656.       begin
  1657.             FirstCharPress := false;
  1658.             repeat
  1659.                MouseStatusWin(L,C,R,MX,MY);
  1660.                if L and (MY = Y1) and (MX = X2+2) then
  1661.                begin
  1662.                   if ActiveNode < TotalNodes then
  1663.                   begin
  1664.                      inc(ActiveNode);
  1665.                      DropListRedisplay(FSP,HiStatus);
  1666.                      if (ActiveForm^.WinNum <> 0) then
  1667.                         WinDrawTop;
  1668.                   end;
  1669.                end;
  1670.                DelayIt(L,(ActiveForm^.WinNum <> 0),WaitTime);
  1671.             until not L;
  1672.       end;
  1673.    end; { MouseSpinDown }
  1674.  
  1675. begin
  1676.    FSP := ActiveForm^.ActiveFieldPtr^.FieldInfo;
  1677.    SpinListKeyHandler := none;
  1678.    with FSP^ do
  1679.    with IO3Vars do
  1680.    begin
  1681.       if (Inkey = SpinUpkey) then
  1682.          SpinDownOne
  1683.       else if (Inkey = SpinDownkey) then
  1684.          SpinUpOne
  1685.       else if (Inkey = 500) and (X = X2+2) then
  1686.          MouseSpinDown
  1687.       else if (Inkey = 500) and (X = X2+3) then
  1688.          MouseSpinUp;
  1689.       with StringLLPtr(ListCfg(DataPtr^).DataSource)^  do
  1690.       begin
  1691.          ListCfg(DataPtr^).ActiveNode := ActiveNode;
  1692.          integer(SourcePtr^) := ActiveNode;
  1693.       end;
  1694.  
  1695.    end;
  1696. end; { SpinListKeyHandler }
  1697.  
  1698. {$IFDEF FOFF}
  1699.    {$F-}
  1700.    {$UNDEF FOFF}
  1701. {$ENDIF}
  1702.  
  1703. procedure SpinListField(FieldID:integer; width:byte; var SelectedItem:integer);
  1704. {}
  1705. var FNP: FieldNodePtr;
  1706. begin
  1707.    FNP := FieldPtr(FieldID);
  1708.    if (FNP <> nil) then
  1709.       with FNP^.FieldInfo^ do
  1710.       begin
  1711.          ListField(FieldID,width,1,SelectedItem);
  1712.          ProcesskeyHook := SpinListKeyHandler;
  1713.          DisplayHook := SpinListDisplay;
  1714.          IconWidth := 4;
  1715.       end;
  1716. end; { SpinListField }
  1717.  
  1718.                            {********************}
  1719.                            {**  SpinDropList  **}
  1720.                            {********************}
  1721.  
  1722. procedure DropSpinList(FSP:FieldSettingsPtr);
  1723. {}
  1724. var Item: longint;
  1725. begin
  1726.    Item := DropTheList(FSP);
  1727.    {update the field if the user didn't escape}
  1728.    if Item <> 0 then
  1729.       with FSP^ do
  1730.       with StringLLPtr(ListCfg(DataPtr^).DataSource)^  do
  1731.       begin
  1732.          ActiveNode := Item;
  1733.          ListCfg(DataPtr^).ActiveNode := ActiveNode;
  1734.          integer(SourcePtr^) := Item;
  1735.       end;
  1736. end; { DropSpinList }
  1737.  
  1738. {$IFOPT F-}
  1739.    {$DEFINE FOFF}
  1740.    {$F+}
  1741. {$ENDIF}
  1742. procedure SpinDropListDisplay(FSP:FieldSettingsPtr;Status:gStatus);
  1743. {}
  1744. begin
  1745.    with FSP^ do
  1746.    begin
  1747.       DrawIcons(X2,Y1,true,true,Active=FldOn);
  1748.       DropListRedisplay(FSP,Status);
  1749.    end;
  1750. end; {SpinDropListDisplay}
  1751.  
  1752. function SpinDropListKeyHandler(InKey:word;X,Y:byte):gAction;
  1753. var
  1754.   FSP:FieldSettingsPtr;
  1755. begin
  1756.    FSP := ActiveForm^.ActiveFieldPtr^.FieldInfo;
  1757.    SpinDropListKeyHandler := none;
  1758.    with FSP^ do
  1759.    with IO3Vars do
  1760.    begin
  1761.       if (InKey = DropDownKey) then
  1762.          DropSpinList(FSP)
  1763.       else if ((Inkey=500) and (X = X2+4)) then
  1764.       begin
  1765.          if ReleaseOnDrop(FSP,4) then
  1766.             DropSpinList(FSP);
  1767.       end
  1768.       else
  1769.          SpinDropListKeyHandler := SpinListKeyHandler(Inkey,X,Y);
  1770.    end;
  1771. end; { SpinDropListKeyHandler }
  1772. {$IFDEF FOFF}
  1773.    {$F-}
  1774.    {$UNDEF FOFF}
  1775. {$ENDIF}
  1776.  
  1777. procedure SpinDropListField(FieldID:integer; width:byte; var SelectedItem:integer);
  1778. {}
  1779. var FNP: FieldNodePtr;
  1780. begin
  1781.    FNP := FieldPtr(FieldID);
  1782.    if (FNP <> nil) then
  1783.       with FNP^.FieldInfo^ do
  1784.       begin
  1785.          SpinListField(FieldID,width,SelectedItem);
  1786.          ProcesskeyHook := SpinDropListKeyHandler;
  1787.          DisplayHook := SpinDropListDisplay;
  1788.          IconWidth := 5;
  1789.       end;
  1790. end; { SpinDropListField }
  1791.  
  1792.                           {**********************}
  1793.                           {**  Edit Drop List  **}
  1794.                           {**********************}
  1795.  
  1796. procedure EditDropListRedisplay(FSP:FieldSettingsPtr;Status:gStatus);
  1797. {}
  1798. begin
  1799.    ScrollDisplay(FSP,Status);
  1800. end; {SpinDropListRedisplay}
  1801.  
  1802. procedure DropEditList(FSP:FieldSettingsPtr);
  1803. {}
  1804. var Item: longint;
  1805. begin
  1806.    Item := DropTheList(FSP);
  1807.    {update the field if the user didn't escape}
  1808.    if Item <> 0 then
  1809.       with FSP^ do
  1810.       begin
  1811.           StringLLPtr(ListCfg(DataPtr^).DataSource)^.ActiveNode := item;
  1812.           with ListCfg(DataPtr^)  do
  1813.              FieldStr := StrLLGetStr(StringLLPtr(DataSource)^,
  1814.                          StringLLPtr(DataSource)^.ActiveNode);
  1815.           StrLocX := 1;
  1816.           CursorX := succ(X1);
  1817.           ScrollInfoPtr(DataPtrS)^.StartChar := 1;
  1818.       end;
  1819. end; { DropEditList }
  1820.  
  1821. {$IFOPT F-}
  1822.    {$DEFINE FOFF}
  1823.    {$F+}
  1824. {$ENDIF}
  1825. procedure EditDropListDisplay(FSP:FieldSettingsPtr;Status:gStatus);
  1826. {}
  1827. begin
  1828.    with FSP^ do
  1829.    begin
  1830.       DrawIcons(X2,Y1,false,true,Active=FldOn);
  1831.       ScrollDisplay(FSP,Status);
  1832.    end;
  1833. end; {EditDropListDisplay}
  1834.  
  1835. function EditDropListKeyHandler(InKey:word;X,Y:byte):gAction;
  1836. var
  1837.   FSP:FieldSettingsPtr;
  1838. begin
  1839.    FSP := ActiveForm^.ActiveFieldPtr^.FieldInfo;
  1840.    EditDropListKeyHandler := none;
  1841.    with FSP^ do
  1842.    with IO3Vars do
  1843.    begin
  1844.       if (InKey = DropDownKey) then
  1845.             DropEditList(FSP)
  1846.       else if ((Inkey=500) and (X = X2+2)) then
  1847.       begin
  1848.          if ReleaseOnDrop(FSP,2) then
  1849.             
  1850.             DropEditList(FSP);
  1851.       end
  1852.       else
  1853.          EditDropListKeyHandler := ScrollKeyHandler(Inkey,X,Y);
  1854.    end;
  1855. end; {EditDropListKeyHandler}
  1856.  
  1857. procedure DisposeEditDropMemory(FNP:FieldSettingsPtr);
  1858. {Disposes of heap memory allocated by scroll and drop data}
  1859. begin
  1860.    DisposeScrollMemory(FNP);
  1861.    DisposeListMemory(FNP);
  1862. end; {DisposeEditDropMemory}
  1863.  
  1864. {$IFDEF FOFF}
  1865.    {$F-}
  1866.    {$UNDEF FOFF}
  1867. {$ENDIF}
  1868.  
  1869. procedure EditDropListField(FieldID:integer; var Strvar:string;FieldL,MaxL:byte);
  1870. {}
  1871. var FNP: FieldNodePtr;
  1872. begin
  1873.    FNP := FieldPtr(FieldID);
  1874.    if (FNP <> nil) then
  1875.       with FNP^.FieldInfo^ do
  1876.       begin
  1877.          ScrollField(FieldID,StrVar,FieldL,MaxL);
  1878.          ProcesskeyHook := EditDropListKeyHandler;
  1879.          DisplayHook := EditDropListDisplay;
  1880.          DisposeHook := DisposeEditDropMemory;
  1881.          IconWidth := 2;
  1882.       end;
  1883. end; { EditDropListField }
  1884.  
  1885.                           {*********************}
  1886.                           {**  HotSpot Field  **}
  1887.                           {*********************}
  1888.  
  1889. procedure HotspotField(FieldID:integer; W,D: byte; Action:gAction);
  1890. {}
  1891. var FNP: FieldNodePtr;
  1892. begin
  1893.    FNP := FieldPtr(FieldID);
  1894.    if (FNP <> nil) then
  1895.       with FNP^.FieldInfo^ do
  1896.       begin
  1897.          HotKeyHook := StandardHotKeyHandler;
  1898.          DisplayHook := NoDisplay;
  1899.          ProcessKeyHook := NoKeyHandler;
  1900.          SuspendHook := SuspendOK;
  1901.          RefreshFieldHook := DoNothing;
  1902.          UpdateVarHook := DoNothing;
  1903.          HotKey := 500;    {indicates that it is a special hotspot field}
  1904.          Visible := false;
  1905.          X2 := X1 + pred(W);
  1906.          Y2 := Y1 + pred(D);
  1907.          OMisc := ord(Action);
  1908.       end;
  1909. end; { HotSpotField }
  1910.  
  1911.                            {********************}
  1912.                            {**  BrowseFields  **}
  1913.                            {********************}
  1914.  
  1915. {$IFOPT F-}
  1916.    {$DEFINE FOFF}
  1917.    {$F+}
  1918. {$ENDIF}
  1919.  
  1920. procedure BrowseDisplay(FSP:FieldSettingsPtr;Status:gStatus);
  1921. {}
  1922. begin
  1923.    BrowseRefresh(ListCfg(FSP^.DataPtr^));
  1924. end; { BrowseDisplay }
  1925.  
  1926. function BrowseKeyHandler(InKey:word;X,Y:byte):gAction;
  1927. {}
  1928. begin
  1929.    BrowseKeyHandler := none;
  1930.    with ActiveForm^.ActiveFieldPtr^.FieldInfo^ do
  1931.       BrowseProcessKey(ListCfg(DataPtr^),Inkey,X,Y,false);
  1932. end; { BrowseKeyHandler }
  1933.  
  1934. procedure BrowseRefreshField(FNP:FieldSettingsPtr);
  1935. {}
  1936. begin
  1937.    with FNP^ do
  1938.       if DataPtr <> nil then
  1939.          ListCfg(DataPtr^).ActiveNode := integer(SourcePtr^);
  1940. end; { BrowseRefreshField }
  1941.  
  1942. {$IFDEF FOFF}
  1943.    {$F-}
  1944.    {$UNDEF FOFF}
  1945. {$ENDIF}
  1946.  
  1947. procedure BrowseField(FieldID:integer; width,depth:byte; var ListDetails: ListCfg);
  1948. {}
  1949. var FNP: FieldNodePtr;
  1950. begin
  1951.    FNP := FieldPtr(FieldID);
  1952.    if (FNP <> nil) then
  1953.       with FNP^.FieldInfo^ do
  1954.       begin
  1955.          SetFieldDefaults(FNP^.FieldInfo);
  1956.          X2 := X1 + pred(width);
  1957.          Y2 := Y1 + pred(depth);
  1958.          Listdetails.X1 := X1;
  1959.          Listdetails.Y1 := Y1;
  1960.          Listdetails.X2 := X2;
  1961.          Listdetails.Y2 := Y2;
  1962.          ProcesskeyHook := BrowseKeyHandler;
  1963.          SuspendHook := SuspendOK;
  1964.          DisplayHook := BrowseDisplay;
  1965.          RefreshFieldHook := BrowseRefreshField;    {change this}
  1966.          FieldStr    := '';
  1967.          FieldFmt    := '';
  1968.          FieldLen    := 0;
  1969.          FieldRules  := 0;
  1970.          OMisc       := ListFld;
  1971.          UsesCursors := true;
  1972.          DataPtr := @Listdetails;
  1973.      end;
  1974.  end; { BrowseField }
  1975.  
  1976.                            {*******************}
  1977.                            {**  Memo Fields  **}
  1978.                            {*******************}
  1979.  
  1980. {$IFOPT F-}
  1981.    {$DEFINE FOFF}
  1982.    {$F+}
  1983. {$ENDIF}
  1984. procedure MemoDisplay(FSP:FieldSettingsPtr;Status:gStatus);
  1985. {}
  1986. begin
  1987.    DisplayMemo(MemoCfg(FSP^.DataPtr^),Status);
  1988.    if Status in [HiStatus,Activate] then
  1989.    begin
  1990.       with MemoCfg(FSP^.DataPtr^) do
  1991.          InsMode(InsertOn);
  1992.       MoveCursor(MemoCfg(FSP^.DataPtr^))
  1993.    end;
  1994. end; {MemoDisplay}
  1995.  
  1996. function MemoKeyHandler(InKey:word;X,Y:byte):gAction;
  1997. {}
  1998. begin
  1999.    MemoKeyHandler := none;
  2000.    with ActiveForm^.ActiveFieldPtr^.FieldInfo^ do
  2001.       MemoProcessKey(MemoCfg(DataPtr^),Inkey,X,Y);
  2002. end; {MemoKeyHandler}
  2003.  
  2004. function MemoSuspend:boolean;
  2005. {}
  2006. begin
  2007.    MemoSuspend := true;
  2008.    with MemoCfg(ActiveForm^.ActiveFieldPtr^.FieldInfo^.DataPtr^) do
  2009.         SetLine(@MemoCfg(ActiveForm^.ActiveFieldPtr^.FieldInfo^.DataPtr^),pred(TopNode)+CursorPosY,LineStr);
  2010.    TurnBlockOff(MemoCfg(ActiveForm^.ActiveFieldPtr^.FieldInfo^.DataPtr^));
  2011. end; {MemoSuspend}
  2012. {$IFDEF FOFF}
  2013.    {$F-}
  2014.    {$UNDEF FOFF}
  2015. {$ENDIF}
  2016.  
  2017. procedure MemoField(FieldID:integer; width,depth:byte;var Memo:MemoCfg);
  2018. {}
  2019. var FNP: FieldNodePtr;
  2020. begin
  2021.    FNP := FieldPtr(FieldID);
  2022.    if (FNP <> nil) then
  2023.    begin
  2024.       with FNP^.FieldInfo^ do
  2025.       begin
  2026.          SetFieldDefaults(FNP^.FieldInfo);
  2027.          X2 := X1 + pred(width);
  2028.          Y2 := Y1 + pred(depth);
  2029.          ProcesskeyHook := MemoKeyHandler;
  2030.          SuspendHook := MemoSuspend;
  2031.          DisplayHook := MemoDisplay;
  2032.          FieldStr    := '';
  2033.          FieldFmt    := '';
  2034.          FieldLen    := 0;
  2035.          FieldRules  := 0;
  2036.          OMisc       := ListFld;
  2037.          UsesCursors := true;
  2038.          DataPtr := @Memo;
  2039.       end;
  2040.       with Memo do
  2041.       begin
  2042.          X1 := FNP^.FieldInfo^.X1;
  2043.          Y1 := FNP^.FieldInfo^.Y1;
  2044.          X2 := X1 + pred(width) - 1;
  2045.          Y2 := Y1 + pred(depth);
  2046.          InWindow := false;      {let IO manager deal with window stuff}
  2047.          if WordWrap then
  2048.             MaxWidth := Width - 2;
  2049.       end;
  2050.    end;
  2051. end; { MemoField }
  2052.  
  2053.                 {**********************************************}
  2054.                 {**  U N I T    I N I T I A L I Z A T I O N  **}
  2055.                 {**********************************************}
  2056.  
  2057. procedure IO3DefaultSettings;
  2058. {}
  2059. begin
  2060.    with IO3Vars do
  2061.    begin
  2062.       SpinUpKey := 408; {Alt-Up}
  2063.       SpinDownkey := 416; {Alt-Down}
  2064.       SpinUp := '';
  2065.       SpinDown := '';
  2066.       DropDownKey := 336; {down}
  2067.       DropDown := '';
  2068.       IconPadLeft := '▐';
  2069.       IconPadRight := '▌';
  2070.    end;
  2071. end; { IO3DefaultSettings }
  2072.  
  2073. procedure GoldIO3Init;
  2074. {}
  2075. begin
  2076.    IO3DefaultSettings;
  2077. end; {GoldIO3Init}
  2078.  
  2079. begin
  2080.    GoldIO3Init;
  2081. end.
  2082.